package com.daocao.common.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

import org.apache.kafka.common.errors.TimeoutException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.daocao.common.config.AESConfig;
import com.daocao.common.constants.HttpStatus;
import com.daocao.common.domain.entity.UmsUserCard;
import com.daocao.common.exception.ServiceException;
import com.daocao.common.mapper.UmsUserCardMapper;
import com.daocao.common.message.UmsUserCardQueryMessage;
import com.daocao.common.service.IUmsUserCardService;
import com.daocao.common.utils.AESUtil;
import com.daocao.common.utils.security.DaoCaoSecurityUtil;

@Service
@Slf4j
public class UmsUserCardServiceImpl extends ServiceImpl<UmsUserCardMapper, UmsUserCard> implements IUmsUserCardService {

    // // 静态变量来保存密钥和 IV
    // private static SecretKey key;
    // private static IvParameterSpec iv;

    // // 在类加载时初始化密钥和 IV
    // static {
    //     try {
    //         key = AESUtil.generateKey(256);
    //         iv = AESUtil.generateIv();
    //     } catch (Exception e) {
    //         e.printStackTrace();
    //     }
    // }
    private final static String RESPONSE_TOPIC_NAME = "response-userCard-topic";
    private final static String TOPIC_NAME = "request-userCard-topic";
    private final ConcurrentHashMap<String, CompletableFuture<List<UmsUserCard>>> responseFutures = new ConcurrentHashMap<>();
    
    @Autowired
    private KafkaTemplate<String, UmsUserCardQueryMessage> kafkaTemplate;

    //private KafkaProducerConfig authenticationManager;

    //public UmsUserCardServiceImpl(KafkaProducerConfig authenticationManager) {
    //    this.authenticationManager = authenticationManager;
    //}

    @Autowired
    private AESConfig aesConfig;

    @Override
    public List<UmsUserCard> selectCardList() {
        List<UmsUserCard> umsUserCards = new ArrayList<>();
        try {
            //String originalText = "377743667744333";
            // 从配置文件中获取 Base64 编码的密钥和 IV
            String base64Key = aesConfig.getBase64Key();
            String base64Iv = aesConfig.getBase64Iv();

            SecretKey key = AESUtil.getKeyFromBase64(base64Key);
            IvParameterSpec iv = AESUtil.getIvFromBase64(base64Iv);
            //String creator = DaoCaoSecurityUtil.getUsername();
            //UmsUserCard umsUserCard = new UmsUserCard();
            //umsUserCard.setId(userId);
            //umsUserCard.setCreator(creator);
            //umsUserCard.setUpdater(creator);
            //umsUserCard.setCardApplyType(0);
            //umsUserCard.setCardReasonType(0);
            //umsUserCard.setCardStatus(0);
            //umsUserCard.setCardNumber(encryptedText);
            //String encryptedText = AESUtil.encrypt(originalText, key, iv);
            //String decryptedText = AESUtil.decrypt(encryptedText, key, iv);
            //System.out.println("Original: " + originalText);
            //System.out.println("Encrypted: " + encryptedText);
            //System.out.println("Decrypted: " + decryptedText);
            //System.out.println("Base64 Key: " + base64Key);
            //System.out.println("Base64 IV: " + base64Iv);
            //baseMapper.insert(umsUserCard);
            


            CompletableFuture<List<UmsUserCard>> future = new CompletableFuture<>();
            String correlationId = UUID.randomUUID().toString(); // 生成唯一的 Correlation ID
            responseFutures.put(correlationId, future);
            // 创建消息，包含用户 ID 和 Correlation ID
            Long userId = DaoCaoSecurityUtil.getUserId();
            UmsUserCardQueryMessage message = new UmsUserCardQueryMessage(userId, correlationId, new ArrayList<>());
            // 发送消息到 Kafka
            kafkaTemplate.send(TOPIC_NAME, correlationId, message);
            System.out.println(message);
            //authenticationManager.kafkaTemplate().send(TOPIC_NAME, correlationId, message);
            // 等待 Kafka 消费者的响应，设置超时时间
            umsUserCards = future.get(10, TimeUnit.SECONDS);
            
            //LambdaQueryWrapper<UmsUserCard> wrapper = new LambdaQueryWrapper<>();
            //wrapper.eq(UmsUserCard::getId, DaoCaoSecurityUtil.getUserId());
            //umsUserCards = baseMapper.selectList(wrapper);

            for (UmsUserCard card : umsUserCards) {
                String decryptedCardNumber = AESUtil.decrypt(card.getCardNumber(), key, iv);
                System.out.println("解密后卡号: " + decryptedCardNumber);
                
                card.setCardNumber(decryptedCardNumber);
            }
           // return umsUserCards;
        } catch (TimeoutException e) {
            // Handle timeout specifically
            System.err.println("Timeout while waiting for Kafka response");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return umsUserCards;
    }

    @Override
    public int updateCardStatus(UmsUserCard umsUserCard) {
        // 获取用户id
        Long userId = DaoCaoSecurityUtil.getUserId();
        umsUserCard.setId(userId);
        // 判断是否登录
        String creator = DaoCaoSecurityUtil.getUsername();
        umsUserCard.setUpdater(creator);
        try {
            // 从配置文件中获取 Base64 编码的密钥和 IV
            String base64Key = aesConfig.getBase64Key();
            String base64Iv = aesConfig.getBase64Iv();

            SecretKey key = AESUtil.getKeyFromBase64(base64Key);
            IvParameterSpec iv = AESUtil.getIvFromBase64(base64Iv);

            // 判断是否存在
            String cardNumber = AESUtil.encrypt(umsUserCard.getCardNumber(), key, iv);
            Integer cardApplyType = umsUserCard.getCardApplyType();
            Integer cardReasonType = umsUserCard.getCardReasonType();
            //Integer cardStatus = umsUserCard.getCardStatus();

            LambdaQueryWrapper<UmsUserCard> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UmsUserCard::getCardNumber, cardNumber)
                .eq(UmsUserCard::getCardApplyType, cardApplyType)
                .eq(UmsUserCard::getCardReasonType, cardReasonType)
                .eq(UmsUserCard::getCardStatus, 0)
                .eq(UmsUserCard::getId, DaoCaoSecurityUtil.getUserId());
            Long count = baseMapper.selectCount(wrapper);
        if (count > 0) {
            throw new ServiceException(HttpStatus.ERROR, "変更項目を変更したら、登録してください。");
        }
            wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(UmsUserCard::getCardNumber, cardNumber)
                   .eq(UmsUserCard::getId, userId);
            umsUserCard.setCardNumber(cardNumber);
            umsUserCard.setCardStatus(1);
            return baseMapper.update(umsUserCard, wrapper);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    @KafkaListener(topics = RESPONSE_TOPIC_NAME, groupId = "userCard-response-group")
    public void handleResponse(UmsUserCardQueryMessage message) {
        String correlationId = message.getCorrelationId();
        List<UmsUserCard> umsUserCards = message.getUmsUserCards();
/*
 * 这段代码的主要意义在于通过 correlationId 确定和匹配从生产端发出的请求，
 * 确保在并发条件下能够正确处理每个用户的请求。
 */
        CompletableFuture<List<UmsUserCard>> future = responseFutures.remove(correlationId);
        if (future != null) {
            future.complete(umsUserCards);
        } else {
            System.err.println("No future found for correlationId: " + correlationId);
        }
    }
}